package org.kl.bf.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.StringTokenizer;

/**
 * @Author hqm
 * @CreateTime 2013-6-24 上午11:18:57
 */

public class CommonUtil {
	private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

	private static SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");

	public static String byteArrayToHexString(byte[] b) {
		StringBuffer sb = new StringBuffer(b.length * 2);
		for (int i = 0; i < b.length; i++) {
			int v = b[i] & 0xFF;
			if (v < 16) {
				sb.append('0');
			}
			sb.append(Integer.toHexString(v));
		}
		return sb.toString().toUpperCase();
	}

	public static byte[] hexStringToByteArray(String s) {
		byte[] b = new byte[s.length() / 2];
		for (int i = 0; i < b.length; i++) {
			int index = i * 2;
			int v = Integer.parseInt(s.substring(index, index + 2), 16);
			b[i] = (byte) v;
		}
		return b;
	}

	public static void copyBytes(byte[] fromBytes, byte[] toBytes,
			int fromOffset, int toOffset, int length) {
		if (length + fromOffset > fromBytes.length) {
			length = fromBytes.length - fromOffset;
		}
		if (length + toOffset > toBytes.length) {
			length = toBytes.length - toOffset;
		}
		for (int i = 0; i < length; i++)
			toBytes[(toOffset + i)] = fromBytes[(fromOffset + i)];
	}

	public static Date parseDate(String dateStr) {
		try {
			return format.parse(dateStr);
		} catch (ParseException e) {
		}
		return null;
	}

	public static String formatDate(Date date) {
		if (date == null) {
			return null;
		}
		return format.format(date);
	}

	public static int compareDate(int year1, int month1, int date1, int year2,
			int month2, int date2) {
		if (year1 < year2)
			return -1;
		if (year1 > year2)
			return 1;
		if (month1 < month2)
			return -2;
		if (month1 > month2)
			return 2;
		if (date1 < date2)
			return -3;
		if (date1 > date2) {
			return 3;
		}
		return 0;
	}

	public static synchronized int compareDate(Date date1, Date date2) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date1);
		int year1 = calendar.get(1);
		int month1 = calendar.get(2);
		int d1 = calendar.get(5);
		calendar.setTime(date2);
		int year2 = calendar.get(1);
		int month2 = calendar.get(2);
		int d2 = calendar.get(5);
		return compareDate(year1, month1, d1, year2, month2, d2);
	}

	public static String formatDateTime(Date date) {
		return dateTimeFormat.format(date);
	}

	public static byte[] intToByteArray(int value) {
		byte[] b = new byte[4];
		for (int i = 0; i < 4; i++) {
			int offset = (b.length - 1 - i) * 8;
			b[i] = (byte) (value >>> offset & 0xFF);
		}
		return b;
	}

	public static int byteArrayToInt(byte[] b) {
		return byteArrayToInt(b, 0);
	}

	public static int byteArrayToInt(byte[] b, int offset) {
		int value = 0;
		int len = Math.min(b.length - offset, 4);
		for (int i = 0; i < len; i++) {
			int shift = (len - 1 - i) * 8;
			value += ((b[(i + offset)] & 0xFF) << shift);
		}
		return value;
	}

	public static byte[] longToByteArray(long i) {
		byte[] buf = new byte[8];
		for (int j = 7; j >= 0; j--) {
			buf[j] = (byte) (int) (i & 0xFF);
			i >>>= 8;
		}
		return buf;
	}

	public static long byteArrayToLong(byte[] buf) {
		return byteArrayToLong(buf, 0);
	}

	public static long byteArrayToLong(byte[] buf, int offset) {
		long i = 0L;
		if (buf.length - offset < 8)
			throw new RuntimeException("Bad Length");
		for (int j = offset; j < 7 + offset; j++) {
			i |= buf[j] & 0xFF;
			i <<= 8;
		}
		i |= buf[(7 + offset)] & 0xFF;
		return i;
	}

	public static Date getStartPointOfThisWeek(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int dayofweek = c.get(7) - 1;
		if (dayofweek == 0)
			dayofweek = 7;
		c.add(5, 1 - dayofweek);
		c.set(11, 0);
		c.set(12, 0);
		c.set(13, 0);
		c.set(14, 0);
		return c.getTime();
	}

	public static Date getEndPointOfThisWeek(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int dayofweek = c.get(7) - 1;
		if (dayofweek == 0)
			dayofweek = 7;
		c.add(5, 7 - dayofweek);
		c.set(11, 23);
		c.set(12, 59);
		c.set(13, 59);
		c.set(14, 999);
		return c.getTime();
	}

	public static Date getStartPointOfThisMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(5, 1);
		c.set(11, 0);
		c.set(12, 0);
		c.set(13, 0);
		c.set(14, 0);
		return c.getTime();
	}

	public static Date getEndPointOfThisMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(2, 1);
		c.set(5, 1);
		c.add(5, -1);
		c.set(11, 23);
		c.set(12, 59);
		c.set(13, 59);
		c.set(14, 999);
		return c.getTime();
	}

	public static Date getStartPointOfPreviousWeek(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int dayofweek = c.get(7) - 1;
		if (dayofweek == 0)
			dayofweek = 7;
		c.add(5, 1 - dayofweek - 7);
		c.set(11, 0);
		c.set(12, 0);
		c.set(13, 0);
		c.set(14, 0);
		return c.getTime();
	}

	public static Date getEndPointOfPreviousWeek(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int dayofweek = c.get(7) - 1;
		if (dayofweek == 0)
			dayofweek = 7;
		c.add(5, 0 - dayofweek);
		c.set(11, 23);
		c.set(12, 59);
		c.set(13, 59);
		c.set(14, 999);
		return c.getTime();
	}

	public static Date getStartPointOfPreviousMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(2, -1);
		c.set(5, 1);
		c.set(11, 0);
		c.set(12, 0);
		c.set(13, 0);
		c.set(14, 0);
		return c.getTime();
	}

	public static Date getEndPointOfPreviousMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(5, 1);
		c.add(5, -1);
		c.set(11, 23);
		c.set(12, 59);
		c.set(13, 59);
		c.set(14, 999);
		return c.getTime();
	}

	public static Date getStartPointOfThisYear(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(2, 0);
		c.set(5, 1);
		c.set(11, 0);
		c.set(12, 0);
		c.set(13, 0);
		c.set(14, 0);
		return c.getTime();
	}

	public static Date getEndPointOfThisYear(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(1, 1);
		c.set(2, 0);
		c.set(5, 1);
		c.add(5, -1);
		c.set(11, 23);
		c.set(12, 59);
		c.set(13, 59);
		c.set(14, 999);
		return c.getTime();
	}

	public static long IP2LongValue(String ipaddress) {
		String[] splits = ipaddress.split("\\.");
		if (splits.length < 4) {
			return -1L;
		}
		long value = 0L;
		for (int i = 0; i < 4; i++) {
			value = (value << 16) + Integer.parseInt(splits[i]);
		}
		return value;
	}

	public static long intIpToLongIp(int intIP) {
		int[] intArray = new int[4];
		intArray[0] = (intIP >>> 24);
		intArray[1] = ((intIP & 0xFFFFFF) >>> 16);
		intArray[2] = ((intIP & 0xFFFF) >>> 8);
		intArray[3] = (intIP & 0xFF);

		long value = 0L;
		for (int i = 0; i < 4; i++) {
			value = (value << 16) + intArray[i];
		}
		return value;
	}

	public static int longIpToIntIp(long longIP) {
		int[] intArray = new int[4];
		intArray[0] = ((int) longIP >>> 48);
		intArray[1] = ((int) longIP >>> 32 & 0xFFFF);
		intArray[2] = ((int) longIP >>> 16 & 0xFFFF);
		intArray[3] = ((int) longIP & 0xFFFF);

		long value = 0L;
		for (int i = 0; i < 4; i++) {
			value = (value << 16) + intArray[i];
		}
		return (intArray[0] << 24) + (intArray[1] << 16) + (intArray[2] << 8)
				+ intArray[3];
	}

	public static int ipToInt(String strIP) {
		int[] ip = new int[4];

		int position1 = strIP.indexOf(".");
		int position2 = strIP.indexOf(".", position1 + 1);
		int position3 = strIP.indexOf(".", position2 + 1);

		ip[0] = Integer.parseInt(strIP.substring(0, position1));
		ip[1] = Integer.parseInt(strIP.substring(position1 + 1, position2));
		ip[2] = Integer.parseInt(strIP.substring(position2 + 1, position3));
		ip[3] = Integer.parseInt(strIP.substring(position3 + 1));
		return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
	}

	public static String intToIP(int intIP) {
		StringBuffer sb = new StringBuffer("");

		sb.append(String.valueOf(intIP >>> 24));
		sb.append(".");

		sb.append(String.valueOf((intIP & 0xFFFFFF) >>> 16));
		sb.append(".");
		sb.append(String.valueOf((intIP & 0xFFFF) >>> 8));
		sb.append(".");
		sb.append(String.valueOf(intIP & 0xFF));
		return sb.toString();
	}

	public static String getSite(String url) {
		int index = url.indexOf("//");
		int urlLength = url.length();
		int index2 = -1;
		for (int i = index < 0 ? 0 : index + 2; i < urlLength; i++) {
			char c = url.charAt(i);
			if ((c == '/') || (c == '?') || (c == '&')) {
				index2 = i;
				break;
			}
		}

		if (index2 < 0) {
			return url;
		}
		String site = url.substring(0, index2);
		return site;
	}

	public static String formatString(String source, int toLength, char fill,
			boolean fillRightSide) {
		if (source == null) {
			return null;
		}
		byte[] bytes = source.getBytes();
		int length = bytes.length;
		if (length == toLength) {
			return source;
		}
		if (length > toLength) {
			return new String(bytes, 0, toLength);
		}
		StringBuffer buffer = new StringBuffer();
		if (fillRightSide) {
			buffer.append(source);
		}
		for (int i = 0; i < toLength - length; i++) {
			buffer.append(fill);
		}
		if (!fillRightSide) {
			buffer.append(source);
		}
		return buffer.toString();
	}

	public static String formatInt32(int value) {
		return formatString(String.valueOf(value), 11, '0', false);
	}

	public static byte[] getBytes(String keyString) {
		if (keyString == null) {
			return null;
		}

		try {
			byte[] key = new byte[16];
			StringTokenizer tokenizer = new StringTokenizer(keyString, ",");
			int index = 0;
			while ((index < key.length) && (tokenizer.hasMoreTokens())) {
				key[(index++)] = Byte.valueOf(tokenizer.nextToken().trim())
						.byteValue();
			}
			return key;
		} catch (Exception e) {
		}
		return null;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void initialObject(Object obj) throws Exception {
		Class objClazz = obj.getClass();
		Field[] fields = objClazz.getDeclaredFields();
		for (Field field : fields) {
			Class type = field.getType();
			String fieldName = field.getName();
			fieldName = fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1);
			String getMethodName = "get" + fieldName;
			String setMethodName = "set" + fieldName;
			Method getMethod = null;
			Method setMethod = null;
			try {
				getMethod = objClazz.getMethod(getMethodName, new Class[0]);
				setMethod = objClazz.getMethod(setMethodName,
						new Class[] { type });
			} catch (Exception e) {
				continue;
			}
			try {
				if (getMethod.invoke(obj, new Object[0]) == null)
					if (type.equals(String.class))
						setMethod.invoke(obj, new Object[] { "" });
					else if (type.getSuperclass().equals(Number.class))
						setMethod.invoke(obj,
								new Object[] { Integer.valueOf(0) });
			} catch (Exception e) {
				throw e;
			}
		}
	}

	public static String formatSqlColumn(String word,String temp) {
		String result = "";
		for (int i = 0; i < word.length(); i++) {
			char c = word.charAt(i);
			if (Character.isUpperCase(c)) {
				result+="_"+String.valueOf(c).toLowerCase();
			}else{
				result+=String.valueOf(c);
			}
		}
		return result;
	}
}